/**
 * 
 */
package utility;

import static constants.OracleWorkflowComponents.*;
import static utility.WorkflowConversionUtil.*;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import utility.Process;

import org.apache.xmlbeans.XmlString;

import wftElements.Activity;
import wftElements.ActivityAttribute;
import wftElements.ActivityAttributeValue;
import wftElements.ActivityTransition;
import wftElements.ItemAttribute;
import wftElements.ItemType;
import wftElements.LookupCode;
import wftElements.LookupType;
import wftElements.Message;
import wftElements.MessageAttribute;
import wftElements.ProcessActivity;
import x2.orgJpdl3.jbpm.Delegation;
import x2.orgJpdl3.jbpm.ProcessDefinitionDocument;
import x2.orgJpdl3.jbpm.ActionDocument.Action;
import x2.orgJpdl3.jbpm.AssignmentDocument.Assignment;
import x2.orgJpdl3.jbpm.DecisionDocument.Decision;
import x2.orgJpdl3.jbpm.EndStateDocument.EndState;
import x2.orgJpdl3.jbpm.EventDocument.Event;
import x2.orgJpdl3.jbpm.MailDocument.Mail;
import x2.orgJpdl3.jbpm.MailNodeDocument.MailNode;
import x2.orgJpdl3.jbpm.NodeDocument.Node;
import x2.orgJpdl3.jbpm.ProcessDefinitionDocument.ProcessDefinition;
import x2.orgJpdl3.jbpm.ProcessStateDocument.ProcessState;
import x2.orgJpdl3.jbpm.ProcessStateDocument.ProcessState.SubProcess;
import x2.orgJpdl3.jbpm.StartStateDocument.StartState;
import x2.orgJpdl3.jbpm.TaskDocument.Task;
import x2.orgJpdl3.jbpm.TaskNodeDocument.TaskNode;
import x2.orgJpdl3.jbpm.TimerDocument.Timer;
import x2.orgJpdl3.jbpm.TransitionDocument.Transition;
import x2.orgJpdl3.jbpm.TransitionDocument.Transition.Condition;

/**
 * @author ashutosh
 * 
 */
public class WorkflowConverter implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	public static Map<String, byte[]> fileMap = new HashMap<String, byte[]>();

	public static Map<String, byte[]> getWorkflowInputStream(File wftFile)
			throws FileNotFoundException, IOException {
		try{
			fileMap.clear();
		extractProcessData(wftFile);
		}catch (Exception e) {
			e.printStackTrace();
		}
		return fileMap;
	}

	/**
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	private static void extractProcessData(File f)
			throws FileNotFoundException, IOException {

		Map<String, Boolean> map = new HashMap<String, Boolean>();

		Process process = new Process();

		String workflowName = f.getName().replace(".wft", "").toUpperCase();
		String mainProcessName = workflowName + "_MAIN";
		process.setMainProcessName(mainProcessName);
		process.setProcessName(workflowName);
		BufferedReader fr = new BufferedReader(new FileReader(f));

		String s = fr.readLine();
		while (s != null) {
			s = s.trim();
			// System.out.println(s);
			if (s.startsWith(BEGIN + SPACE + MESSAGE)) {
			}
			// 1. Ignore if the line starts with # or is blank
			if (s.startsWith(HASH) || "".equals(s)) {
			}

			// 2. Populate version etc info if present
			else if (s.startsWith(VERSION_MAJOR)) {
				process.setVersionMajor(getTextBetweenFirstQuotes(s));

			} else if (s.startsWith(VERSION_MINOR)) {
				process.setVersionMinor(getTextBetweenFirstQuotes(s));

			} else if (s.startsWith(LANGUAGE)) {
				process.setLanguage(getTextBetweenFirstQuotes(s));

			} else if (s.startsWith(ACCESS_LEVEL)) {
				process
						.setAccessLevel(new Integer(
								getTextBetweenFirstQuotes(s)));

			}

			// 3. Ignore all the definitions i.e the contents between definition
			// DEFINE and its end;
			else if (s.startsWith(DEFINE)) {
				String elementDefined = s.split(" ")[1];
				s = fr.readLine();
				s = s.trim();
				while (s != null
						&& !s.equalsIgnoreCase(END + SPACE + elementDefined)) {
					s = fr.readLine();
					s = s.trim();
				}
			}

			// 4. Read everything that starts with Begin and then populate the
			// base

			// What all can be there

			// LOOKUP_TYPE
			else if (s.startsWith(BEGIN + SPACE + LOOKUP_TYPE)) {
				s = extractLookupTypes(process, fr, s);
			}

			// MESSAGE
			else if (s.startsWith(BEGIN + SPACE + MESSAGE)) {
				s = extractMessages(process, fr, s);
			}

			// ITEM_TYPE
			else if (s.startsWith(BEGIN + SPACE + ITEM_TYPE)) {
				s = extractItemTypes(process, fr, s);
			}

			// ACTIVITY
			else if (s.startsWith(BEGIN + SPACE + ACTIVITY)) {
				if(s.endsWith("_MAIN\"")){
					mainProcessName = getMainProcessName(s, mainProcessName);
					process.setMainProcessName(mainProcessName);
				}
				s = extractActivities(process, fr, s);
			}

			s = fr.readLine();
		}

		populateProcessDefinitionFile(process, map);
	}

	private static String getMainProcessName(String s, String mainProcessName) {
		String[] sArr = s.split(" ");
		return getTextBetweenFirstQuotes(sArr[sArr.length - 1]);
	}

	/**
	 * @param process
	 * @param fr
	 * @param s
	 * @return
	 * @throws IOException
	 */
	private static String extractLookupTypes(Process process,
			BufferedReader fr, String s) throws IOException {
		LookupType lookupType = new LookupType();
		String lookupTypeName = s.split(" ")[2].replaceAll("\"", "");
		lookupType.setName(lookupTypeName);
		s = fr.readLine();
		if (s != null) {
			s = s.trim(); // This is next line after the lookup type
			// begin
		}
		while (s != null && !s.equalsIgnoreCase(END + SPACE + LOOKUP_TYPE)) {
			if (s.startsWith(PROTECT_LEVEL)) {
				lookupType.setProtectLevel(new Integer(
						getTextBetweenFirstQuotes(s)));
			} else if (s.startsWith(CUSTOM_LEVEL)) {
				lookupType.setCustomLevelNumber(new Integer(
						getTextBetweenFirstQuotes(s)));
			} else if (s.startsWith(DISPLAY_NAME)) {
				lookupType.setDisplayName(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(ITEM_TYPE)) {
				lookupType.setItemTypeName(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(DESCRIPTION)) {
				lookupType.setDescription(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(BEGIN + SPACE + LOOKUP_CODE)) {
				s = extractLookupCodes(fr, s, lookupType);
			}
			s = fr.readLine();

			if (s != null) {
				s = s.trim(); // This is next line after the lookup code
				// begin
			}
		}
		process.getLookupTypeList().add(lookupType);
		return s;
	}

	/**
	 * @param fr
	 * @param s
	 * @param lookupType
	 * @return
	 * @throws IOException
	 */
	private static String extractLookupCodes(BufferedReader fr, String s,
			LookupType lookupType) throws IOException {
		LookupCode lookupCode = new LookupCode();
		String lookupCodeName = s.split(" ")[2].replaceAll("\"", "");
		lookupCode.setName(lookupCodeName);
		s = fr.readLine();
		if (s != null) {
			s = s.trim(); // This is next line after the lookup
			// code begin
		}
		while (s != null && !s.equalsIgnoreCase(END + SPACE + LOOKUP_CODE)) {
			if (s.startsWith(MEANING)) {
				lookupCode.setMeaning(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(DESCRIPTION)) {
				lookupCode.setDescription(getTextBetweenFirstQuotes(s));
			}
			s = fr.readLine();
			if (s != null) {
				s = s.trim(); // This is next line after the
				// lookup code begin
			}
		}
		// Here the line is at the end of lookup code
		lookupType.getLookupCodeList().add(lookupCode);
		return s;
	}

	/**
	 * @param process
	 * @param fr
	 * @param s
	 * @return
	 * @throws IOException
	 */
	private static String extractMessages(Process process, BufferedReader fr,
			String s) throws IOException {
		Message message = new Message();
		Object[] strArr = getTextsBetweenQuotes(s);
		String itemTypeName = (String) strArr[0];
		message.setItemTypeName(itemTypeName);
		String messageName = (String) strArr[1];
		message.setName(messageName);
		s = fr.readLine();
		if (s != null) {
			s = s.trim(); // This is next line after the lookup type
			// begin
		}
		while (s != null && !s.equalsIgnoreCase(END + SPACE + MESSAGE)) {
			if (s.startsWith(PROTECT_LEVEL)) {
				message.setProtectLevel(new Integer(
						getTextBetweenFirstQuotes(s)));
			} else if (s.startsWith(CUSTOM_LEVEL)) {
				message.setCustomLevelNumber(new Integer(
						getTextBetweenFirstQuotes(s)));
			} else if (s.startsWith(DISPLAY_NAME)) {
				message.setDisplayName(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(SUBJECT)) {
				message.setSubject(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(DESCRIPTION)) {
				message.setDescription(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(BODY)) {
				StringBuffer body = new StringBuffer();
				String bodyLine = getTextsAfterEqualToSign(s);
				if (bodyLine.startsWith("\"") && bodyLine.endsWith("\"")) {
					message.setBody(getTextBetweenFirstQuotes(s));
				} else if (bodyLine.startsWith("\"")
						&& !bodyLine.endsWith("\"")) {
					body.append(getTextAfterFirstQuote(s));
					s = fr.readLine();
					if (s != null) {
						s = s.trim(); // This is next line after the
						// lookup type begin
					}
					while (s != null
							&& !((!s.startsWith("\"")) && s.endsWith("\""))) {
						if ((!s.startsWith("\"")) && !s.endsWith("\"")) {
							body.append(s);
							s = fr.readLine();
							if (s != null) {
								s = s.trim(); // This is next line after
								// the lookup type begin
							}
						}
					}
					body.append(getTextBeforeLastQuote(s));
					message.setBody(body.toString());
				}
				// read msg body till u get " start and end
			} else if (s.startsWith(HTML_BODY)) {
				StringBuffer body = new StringBuffer();
				String bodyLine = getTextsAfterEqualToSign(s);
				if (bodyLine.startsWith("\"") && bodyLine.endsWith("\"")) {
					message.setHtmlBody(getTextBetweenFirstQuotes(s));
				} else if (bodyLine.startsWith("\"")
						&& !bodyLine.endsWith("\"")) {
					body.append(getTextAfterFirstQuote(s));
					s = fr.readLine();
					if (s != null) {
						s = s.trim(); // This is next line after the
						// lookup type begin
					}
					while (s != null
							&& !((!s.startsWith("\"")) && s.endsWith("\""))) {
						if ((!s.startsWith("\"")) && !s.endsWith("\"")) {
							body.append(s);
							s = fr.readLine();
							if (s != null) {
								s = s.trim(); // This is next line after
								// the lookup type begin
							}
						}
					}
					body.append(getTextBeforeLastQuote(s));
					message.setHtmlBody(body.toString());
				}
				// read msg htmlbody till u get " start and end
			} else if (s.startsWith(DEFAULT_PRIORITY)) {
				message.setDefaultPriority(new Integer(
						getTextBetweenFirstQuotes(s)));
			} else if (s.startsWith(READ_ROLE)) {
				message.setReadRoleName(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(WRITE_ROLE)) {
				message.setWriteRoleName(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(BEGIN + SPACE + MESSAGE_ATTRIBUTE)) {
				s = extractMessageAttributes(fr, s, message);
			}
			s = fr.readLine();
			if (s != null) {
				s = s.trim(); // This is next line after the lookup code
				// begin
			}
		}
		process.getMsgList().add(message);
		return s;
	}

	/**
	 * @param fr
	 * @param s
	 * @param message
	 * @return
	 * @throws IOException
	 */
	private static String extractMessageAttributes(BufferedReader fr, String s,
			Message message) throws IOException {
		MessageAttribute msgAttr = new MessageAttribute();
		String msgAttrName = s.split(" ")[2].replaceAll("\"", "");
		msgAttr.setName(msgAttrName);
		s = fr.readLine();
		if (s != null) {
			s = s.trim(); // This is next line after the msgAttr
			// begin
		}
		while (s != null
				&& !s.equalsIgnoreCase(END + SPACE + MESSAGE_ATTRIBUTE)) {
			if (s.startsWith(DISPLAY_NAME)) {
				msgAttr.setDisplayName(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(DESCRIPTION)) {
				msgAttr.setDescription(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(TYPE)) {
				msgAttr.setType(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(SUBTYPE)) {
				msgAttr.setSubType(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(FORMAT)) {
				msgAttr.setFormat(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(VALUE_TYPE)) {
				msgAttr.setValueType(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(DEFAULT)) {
				msgAttr.setDefaultValue(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(ATTACH)) {
				msgAttr.setAttach("Y".equals(getTextBetweenFirstQuotes(s)));
			}
			s = fr.readLine();
			if (s != null) {
				s = s.trim(); // This is next line after the
				// lookup code begin
			}
		}
		// Here the line is at the end of msg attribute
		message.getMsgAttrList().add(msgAttr);
		return s;
	}

	/**
	 * @param process
	 * @param fr
	 * @param s
	 * @return
	 * @throws IOException
	 */
	private static String extractItemTypes(Process process, BufferedReader fr,
			String s) throws IOException {
		ItemType itemType = new ItemType();
		String itemTypeName = s.split(" ")[2].replaceAll("\"", "");
		itemType.setName(itemTypeName);
		s = fr.readLine();
		if (s != null) {
			s = s.trim(); // This is next line after the lookup type
			// begin
		}
		while (s != null && !s.equalsIgnoreCase(END + SPACE + ITEM_TYPE)) {
			if (s.startsWith(PROTECT_LEVEL)) {
				itemType.setProtectLevel(new Integer(
						getTextBetweenFirstQuotes(s)));
			} else if (s.startsWith(CUSTOM_LEVEL)) {
				itemType.setCustomLevelNumber(new Integer(
						getTextBetweenFirstQuotes(s)));
			} else if (s.startsWith(PERSISTENCE_DAYS)) {
				itemType.setPersistenceDays(new Integer(
						getTextBetweenFirstQuotes(s)));
			} else if (s.startsWith(DISPLAY_NAME)) {
				itemType.setDisplayName(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(PERSISTENCE_TYPE)) {
				itemType.setPersistenceType(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(WF_SELECTOR)) {
				itemType.setWfSelector(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(DESCRIPTION)) {
				itemType.setDescription(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(READ_ROLE)) {
				itemType.setReadRoleName(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(WRITE_ROLE)) {
				itemType.setWriteRoleName(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(EXECUTE_ROLE)) {
				itemType.setExecuteRoleName(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(BEGIN + SPACE + ITEM_ATTRIBUTE)) {
				s = extractItemAttributes(fr, s, itemType);
			}
			s = fr.readLine();

			if (s != null) {
				s = s.trim(); // This is next line after the lookup code
				// begin
			}
		}
		process.getItemTypeList().add(itemType);
		return s;
	}

	/**
	 * @param fr
	 * @param s
	 * @param itemType
	 * @return
	 * @throws IOException
	 */
	private static String extractItemAttributes(BufferedReader fr, String s,
			ItemType itemType) throws IOException {
		ItemAttribute itemAttr = new ItemAttribute();
		String itemAttrName = s.split(" ")[2].replaceAll("\"", "");
		itemAttr.setName(itemAttrName);
		s = fr.readLine();
		if (s != null) {
			s = s.trim(); // This is next line after the
			// itemtype begin
		}
		while (s != null && !s.equalsIgnoreCase(END + SPACE + ITEM_ATTRIBUTE)) {
			if (s.startsWith(PROTECT_LEVEL)) {
				itemAttr.setProtectLevel(new Integer(
						getTextBetweenFirstQuotes(s)));
			} else if (s.startsWith(CUSTOM_LEVEL)) {
				itemAttr.setCustomLevelNumber(new Integer(
						getTextBetweenFirstQuotes(s)));
			} else if (s.startsWith(DESCRIPTION)) {
				itemAttr.setDescription(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(DISPLAY_NAME)) {
				itemAttr.setDisplayName(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(TYPE)) {
				itemAttr.setType(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(FORMAT)) {
				itemAttr.setFormat(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(VALUE_TYPE)) {
				itemAttr.setValueType(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(DEFAULT)) {
				itemAttr.setDefaultValue(getTextBetweenFirstQuotes(s));
			}
			s = fr.readLine();
			if (s != null) {
				s = s.trim(); // This is next line after the
				// lookup code begin
			}
		}
		// Here the line is at the end of lookup code
		itemType.getItemAttrList().add(itemAttr);
		return s;
	}

	/**
	 * @param process
	 * @param fr
	 * @param s
	 * @return
	 * @throws IOException
	 */
	private static String extractActivities(Process process, BufferedReader fr,
			String s) throws IOException {
		Activity activity = new Activity();
		Object[] strArr = getTextsBetweenQuotes(s);
		String itemTypeName = (String) strArr[0];
		activity.setItemTypeName(itemTypeName);
		String activityName = (String) strArr[1];
		activity.setName(activityName);
		s = fr.readLine();
		if (s != null) {
			s = s.trim(); // This is next line after the lookup type
			// begin
		}
		while (s != null && !s.equalsIgnoreCase(END + SPACE + ACTIVITY)) {
			if (s.startsWith(PROTECT_LEVEL)) {
				activity.setProtectLevel(new Integer(
						getTextBetweenFirstQuotes(s)));
			} else if (s.startsWith(CUSTOM_LEVEL)) {
				activity.setCustomLevelNumber(new Integer(
						getTextBetweenFirstQuotes(s)));
			} else if (s.startsWith(DISPLAY_NAME)) {
				activity.setDisplayName(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(TYPE)) {
				activity.setType(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(DESCRIPTION)) {
				activity.setDescription(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(FUNCTION)) {
				activity.setFunction(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(FUNCTION_TYPE)) {
				activity.setFunctionType(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(ICON_NAME)) {
				activity.setIconName(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(RESULT_TYPE)) {
				activity.setResultType(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(RERUN)) {
				activity.setReRun(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(COST)) {
				activity.setCost(new Integer(getTextBetweenFirstQuotes(s)));
			} else if (s.startsWith(READ_ROLE)) {
				activity.setReadRoleName(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(WRITE_ROLE)) {
				activity.setWriteRoleName(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(EXECUTE_ROLE)) {
				activity.setExecuteRoleName(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(MESSAGE)) {
				activity.setMessage(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(ERROR_PROCESS)) {
				activity.setErrorProcess(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(ERROR_ITEM_TYPE)) {
				activity.setErrorItemType(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(EXPAND_ROLE)) {
				activity.setExpandRole("Y"
						.equalsIgnoreCase(getTextBetweenFirstQuotes(s)));
			} else if (s.startsWith(RUNNABLE)) {
				activity.setRunnable("Y"
						.equalsIgnoreCase(getTextBetweenFirstQuotes(s)));
			} else if (s.startsWith(EVENT_FILTER)) {
				activity.setEventFilter(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(EVENT_TYPE)) {
				activity.setEventType(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(BEGIN + SPACE + ACTIVITY_ATTRIBUTE)) {
				s = extractActivityAttributes(fr, s, activity);
			} else if (s.startsWith(BEGIN + SPACE + PROCESS_ACTIVITY)) {
				s = extractProcessActivities(fr, s, activity);
			}
			s = fr.readLine();

			if (s != null) {
				s = s.trim(); // This is next line after the lookup code
				// begin
			}
		}
		process.getActList().add(activity);
		return s;
	}

	/**
	 * @param fr
	 * @param s
	 * @param activity
	 * @return
	 * @throws IOException
	 */
	private static String extractProcessActivities(BufferedReader fr, String s,
			Activity activity) throws IOException {
		ProcessActivity processActivity = new ProcessActivity();
		String label = s.split(" ")[2].replaceAll("\"", "");
		processActivity.setLabel(label);
		s = fr.readLine();
		if (s != null) {
			s = s.trim(); // This is next line after the lookup
			// code begin
		}
		while (s != null && !s.equalsIgnoreCase(END + SPACE + PROCESS_ACTIVITY)) {
			if (s.startsWith(ACTIVITY_ITEM_TYPE)) {
				processActivity.setItemTypeName(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(ACTIVITY_NAME)) {
				processActivity.setActivityName(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(START_END)) {
				processActivity.setStartEnd(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(DEFAULT_RESULT)) {
				processActivity.setDefaultResult(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(ICON_GEOMETRY)) {
				processActivity.setIconGeometry(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(VALUE_TYPE)) {
				processActivity.setValueType(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(PERFORM_ROLE)) {
				processActivity
						.setPerformRoleName(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(USER_COMMENT)) {
				processActivity.setUserComment(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(BEGIN + SPACE + ACTIVITY_ATTRIBUTE_VALUE)) {
				ActivityAttributeValue actAttrVal = new ActivityAttributeValue();
				String name = s.split(" ")[2].replaceAll("\"", "");
				actAttrVal.setName(name);
				s = fr.readLine();
				if (s != null) {
					s = s.trim(); // This is next line after the
					// lookup code begin
				}
				while (s != null
						&& !s.equalsIgnoreCase(END + SPACE
								+ ACTIVITY_ATTRIBUTE_VALUE)) {
					if (s.startsWith(VALUE) && !s.startsWith(VALUE_TYPE)) {
						actAttrVal.setValue(getTextBetweenFirstQuotes(s));
					} else if (s.startsWith(VALUE_TYPE)) {
						actAttrVal.setValueType(getTextBetweenFirstQuotes(s));
					}
					s = fr.readLine();
					if (s != null) {
						s = s.trim(); // This is next line after
						// the lookup code begin
					}
				}
				// Here the line is at the end of lookup code
				processActivity.getActAttrVal().add(actAttrVal);
			} else if (s.startsWith(BEGIN + SPACE + ACTIVITY_TRANSITION)) {
				ActivityTransition actTransition = new ActivityTransition();
				Object[] strArrTransition = getTextsBetweenQuotes(s);
				String fromProcessName = (String) strArrTransition[0];
				actTransition.setFromProcessActivityName(fromProcessName);
				String toProcessName = (String) strArrTransition[1];
				actTransition.setToProcessActivityName(toProcessName);
				s = fr.readLine();
				if (s != null) {
					s = s.trim(); // This is next line after the
					// lookup code begin
				}
				while (s != null
						&& !s.equalsIgnoreCase(END + SPACE
								+ ACTIVITY_TRANSITION)) {
					if (s.startsWith(ARROW_GEOMETRY)) {
						actTransition
								.setArrowGeometry(getTextBetweenFirstQuotes(s));
					}
					s = fr.readLine();
					if (s != null) {
						s = s.trim(); // This is next line after
						// the lookup code begin
					}
				}
				// Here the line is at the end of lookup code
				processActivity.getActTransition().add(actTransition);
			}
			s = fr.readLine();
			if (s != null) {
				s = s.trim(); // This is next line after the
				// lookup code begin
			}
		}
		// Here the line is at the end of lookup code
		activity.getProcessActivityList().add(processActivity);
		return s;
	}

	/**
	 * @param fr
	 * @param s
	 * @param activity
	 * @return
	 * @throws IOException
	 */
	private static String extractActivityAttributes(BufferedReader fr,
			String s, Activity activity) throws IOException {
		ActivityAttribute actAttr = new ActivityAttribute();
		String actAttrName = s.split(" ")[2].replaceAll("\"", "");
		actAttr.setName(actAttrName);
		s = fr.readLine();
		if (s != null) {
			s = s.trim(); // This is next line after the lookup
			// code begin
		}
		while (s != null
				&& !s.equalsIgnoreCase(END + SPACE + ACTIVITY_ATTRIBUTE)) {
			if (s.startsWith(VALUE_TYPE)) {
				actAttr.setValueType(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(DEFAULT)) {
				actAttr.setDefaultValue(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(DISPLAY_NAME)) {
				actAttr.setDisplayName(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(TYPE)) {
				actAttr.setType(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(FORMAT)) {
				actAttr.setFormat(getTextBetweenFirstQuotes(s));
			} else if (s.startsWith(DESCRIPTION)) {
				actAttr.setDescription(getTextBetweenFirstQuotes(s));
			}
			s = fr.readLine();
			if (s != null) {
				s = s.trim(); // This is next line after the
				// lookup code begin
			}
		}
		// Here the line is at the end of lookup code
		activity.getActivityAttrList().add(actAttr);
		return s;
	}

	private static void populateProcessDefinitionFile(Process process,
			Map<String, Boolean> map) throws IOException {

		// Now all the components are read and now it is needed to populate same
		// in the process then to document

		// Start by creating a <root> element that will contain
		// the children built by this method.
		ProcessDefinitionDocument rootDoc = ProcessDefinitionDocument.Factory
				.newInstance();
		ProcessDefinitionDocument.ProcessDefinition root = rootDoc
				.addNewProcessDefinition();

		Activity mainAct = getActivityByName(process.getMainProcessName(),
				process);

		// Now evaluate everything based on the main act and process

		makeProcessDocument(process, rootDoc, root, mainAct, map);
	}

	/**
	 * @param process
	 * @param rootDoc
	 * @param root
	 * @param mainAct
	 * @param map
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	private static void makeProcessDocument(Process process,
			ProcessDefinitionDocument rootDoc,
			ProcessDefinitionDocument.ProcessDefinition root, Activity mainAct,
			Map<String, Boolean> map) throws FileNotFoundException, IOException {

		if (mainAct == null) {
			throw new RuntimeException("Main Activity Does not Exist");
		}

		// Add name of the process
		root.setName(mainAct.getDisplayName());

		// Add description
		String desc = mainAct.getDescription();
		root.addDescription(desc == null ? mainAct.getDisplayName()
				+ " Process" : desc);

		ProcessActivity startAct = getProcessActivityByName("start", mainAct);

		StartState startState = root.addNewStartState();
		startState.setName(startAct.getActivityName());
		startState.addDescription(startAct.getDescription() == null ? "Start "
				+ mainAct.getDisplayName() + " Process" : startAct
				.getDescription());

		// From here its automation

		for (ActivityTransition actTransition : startAct.getActTransition()) {
			if (actTransition.getToProcessActivityName() != null) {
				Transition transition = startState.addNewTransition();
				String name = getActivityByName(
						actTransition.getToProcessActivityName(), process)
						.getDisplayName();
				transition.setTo(name);

				if (startAct.getActTransition().size() != 1)
					transition.setName(getActivityByName(
							actTransition.getToProcessActivityName(), process)
							.getDisplayName());
				transition.addDescription(getActivityByName(
						actTransition.getToProcessActivityName(), process)
						.getDisplayName());
				populateTransitionBasedNodes(actTransition, rootDoc, process,
						mainAct, root, map);
			}
		}

		fileMap.put(mainAct.getDisplayName(), rootDoc.toString().getBytes());
	}

	private static void populateTransitionBasedNodes(
			ActivityTransition actTransition,
			ProcessDefinitionDocument rootDoc, Process process,
			Activity mainAct, ProcessDefinition root, Map<String, Boolean> map)
			throws FileNotFoundException, IOException {
		// Here populate the nodes based on the transition to element.
		// Now this the next activity to be added
		// This activity may be a function or a notification

		ProcessActivity pAct = getProcessActivityByName(actTransition
				.getToProcessActivityName(), mainAct);
		Activity thisAct = getActivityByName(pAct.getActivityName(), process);

		// If the activity calls one of the following methods that means these
		// are the corresponding function. These can be compare or the assign or
		// error or others. Please see the documentation for more details. If it
		// is not a custom function call that means the activity has to be
		// present in the reusable components or wf_std. For example in MSJ,
		// Qualcomm_Std has been made a library reusable in each and every
		// project. So, in this case that can be considered as inherent and a
		// reusable library can be developed.

		if (thisAct != null && thisAct.getIconName() != null
				&& thisAct.getIconName().startsWith("PROCESS")) {
			writeProcesses(pAct, mainAct, thisAct, rootDoc, root, process, map);

		} else if (thisAct != null
				&& thisAct.getIconName() != null
				&& (thisAct.getIconName().startsWith("NOTIFY") || thisAct
						.getIconName().startsWith("NTF"))) {

			writeNotifications(pAct, mainAct, thisAct, rootDoc, root, process,
					map);

		} else if (thisAct != null && thisAct.getFunction() != null) {
			writeFunctions(process, mainAct, rootDoc, root, pAct, thisAct, map);
		}

	}

	/**
	 * @param pAct
	 * @param thisAct
	 * @param mainAct
	 * @param process
	 * @param root
	 * @param rootDoc
	 * @param map
	 * @throws IOException
	 * @throws FileNotFoundException
	 */
	private static void writeNotifications(ProcessActivity pAct,
			Activity mainAct, Activity thisAct,
			ProcessDefinitionDocument rootDoc, ProcessDefinition root,
			Process process, Map<String, Boolean> map)
			throws FileNotFoundException, IOException {

		Boolean bool = map.get(thisAct.getDisplayName());
		if (bool == null || !bool) {
			TaskNode node = root.addNewTaskNode();
			node.setName(thisAct.getDisplayName());
			node.addDescription(thisAct.getDisplayName());

			Event event = node.addNewEvent();
			event.setType("node-enter");
			Mail mail = event.addNewMail();
			mail.setTo("#{" + pAct.getPerformRoleName() + "}");
			mail.setName("Mail To " + pAct.getPerformRoleName());
			Message msg = getMessageByName(thisAct.getMessage(), process);
			XmlString str = mail.addNewSubject();
			str.setStringValue(msg.getSubject());
			XmlString str1 = mail.addNewText();
			str1.setStringValue(msg.getBody() == null ? msg.getHtmlBody() : msg
					.getBody());

			Task task = node.addNewTask();
			task.addDescription(thisAct.getDisplayName());
			Assignment assignment = task.addNewAssignment();
			assignment.setActorId("#{" + pAct.getPerformRoleName() + "}");

			// Create timer based on the configurations
			// take care of AND OR join operation. here its separate
			map.put(node.getName(), true);
			addTransitions(pAct, mainAct, rootDoc, root, process, map, node);
		}
	}

	private static void writeTimer(TaskNode node, String value, String string,
			boolean repeat, Map<String, Boolean> map) {
		Boolean boolTimeout = map.get(node.getName() + "Timeout Timer");
		Boolean boolLoop = map.get(node.getName() + "Loop Timer");
		if (node != null && boolLoop != null && boolLoop && repeat) {

		} else if (node != null && boolTimeout != null && boolTimeout
				&& !repeat) {

		} else if (node != null) {
			Timer timer = node.addNewTimer();
			timer.setDuedate(Integer.valueOf(value) / 1440 + " days");
			if (repeat) {
				timer.setName(node.getName() + "Loop Timer");
				timer.setRepeat("yes");
				Action action = timer.addNewAction();
				action.setClass1("com.tcs."
						+ WorkflowConversionUtil
								.getStringSplitForWhiteSpaces(node.getName())
						+ "LoopCounterActionHandler");
				map.put(node.getName() + "Loop Timer", true);
			} else {
				timer.setName(node.getName() + "Timeout Timer");
				timer.setTransition("#Timeout");
				map.put(node.getName() + "Timeout Timer", true);
			}
		}
	}

	/**
	 * @param pAct
	 * @param mainAct
	 * @param rootDoc
	 * @param root
	 * @param process
	 * @param map
	 * @param node
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	private static void addTransitions(ProcessActivity pAct, Activity mainAct,
			ProcessDefinitionDocument rootDoc, ProcessDefinition root,
			Process process, Map<String, Boolean> map, TaskNode node)
			throws FileNotFoundException, IOException {

		for (ActivityTransition actTran : pAct.getActTransition()) {
			if (actTran.getToProcessActivityName() != null) {
				Transition transition = node.addNewTransition();
				String name = getActivityByName(
						getProcessActivityByName(
								actTran.getToProcessActivityName(), mainAct)
								.getActivityName(), process).getDisplayName();
				if (name != null) {

					ProcessActivity pNextAct = getProcessActivityByName(actTran
							.getToProcessActivityName(), mainAct);
					Activity thisAct = getActivityByName(pNextAct
							.getActivityName(), process);

					for (ActivityAttributeValue attrValue : pAct
							.getActAttrVal()) {
						if (attrValue.getName() != null
								&& attrValue.getName().equalsIgnoreCase(
										"#Timeout")) {
							boolean repeat = false;

							//
							for (ActivityTransition actTranCheck : pAct
									.getActTransition()) {
								if (actTranCheck.getToProcessActivityName() != null) {
									String nameCheck = getActivityByName(
											getProcessActivityByName(
													actTranCheck
															.getToProcessActivityName(),
													mainAct).getActivityName(),
											process).getDisplayName();
									if (nameCheck != null) {

										ProcessActivity pActCheck = getProcessActivityByName(
												actTranCheck
														.getToProcessActivityName(),
												mainAct);
										Activity thisActCheck = getActivityByName(
												pActCheck.getActivityName(),
												process);
										if (thisActCheck != null
												&& thisActCheck.getFunction() != null
												&& thisActCheck
														.getFunction()
														.equalsIgnoreCase(
																"WF_STANDARD.LOOPCOUNTER")) {
											repeat = true;

										}
									}
								}
							}

							//

							writeTimer(node, attrValue.getValue(), "#Timeout",
									repeat, map);
						}
					}

					// If the activity calls one of the following methods that
					// means these
					// are the corresponding function. These can be compare or
					// the assign or
					// error or others. Please see the documentation for more
					// details. If it
					// is not a custom function call that means the activity has
					// to be
					// present in the reusable components or wf_std. For example
					// in MSJ,
					// Qualcomm_Std has been made a library reusable in each and
					// every
					// project. So, in this case that can be considered as
					// inherent and a
					// reusable library can be developed.

					if (thisAct != null
							&& thisAct.getFunction() != null
							&& thisAct.getFunction().equalsIgnoreCase(
									"WF_STANDARD.ORJOIN")) {
						for (ActivityTransition actNextTran : pNextAct
								.getActTransition()) {
							if (actNextTran.getToProcessActivityName() != null) {
								name = getActivityByName(
										getProcessActivityByName(
												actNextTran
														.getToProcessActivityName(),
												mainAct).getActivityName(),
										process).getDisplayName();

							}
						}
					}

					if (thisAct != null
							&& thisAct.getFunction() != null
							&& thisAct.getFunction().equalsIgnoreCase(
									"WF_STANDARD.LOOPCOUNTER")) {
						for (ActivityTransition actNextTran : pNextAct
								.getActTransition()) {
							if (actNextTran.getToProcessActivityName() != null
									&& actNextTran.getFromProcessActivityName() != null
									&& actNextTran.getFromProcessActivityName()
											.equalsIgnoreCase("LOOP")) {
								name = getActivityByName(
										getProcessActivityByName(
												actNextTran
														.getToProcessActivityName(),
												mainAct).getActivityName(),
										process).getDisplayName();

							}
							if (actNextTran.getToProcessActivityName() != null
									&& actNextTran.getFromProcessActivityName() != null
									&& actNextTran.getFromProcessActivityName()
											.equalsIgnoreCase("EXIT")) {
								// If exit then put this transition as hidden,
								// as the value will be returned by the handler
								// in this case

								Transition transitionExit = node
										.addNewTransition();

								String nameExit = getActivityByName(
										getProcessActivityByName(
												actNextTran
														.getToProcessActivityName(),
												mainAct).getActivityName(),
										process).getDisplayName();
								transitionExit.setTo(nameExit);
								transitionExit.addDescription(nameExit);
								transitionExit.setName("No Response");
							}
						}
					}
				}
				transition.setTo(name);
				transition.addDescription(name);
				if (pAct.getActTransition().size() != 1) {
					transition.setName(actTran.getFromProcessActivityName()
							.equals("*") ? name : actTran
							.getFromProcessActivityName());
				}

				populateTransitionBasedNodes(actTran, rootDoc, process,
						mainAct, root, map);
			}
		}
	}

	/**
	 * @param pAct
	 * @param thisAct
	 * @param mainAct
	 * @param root
	 * @param rootDoc
	 * @param rootDoc
	 * @param root
	 * @param process
	 * @param map
	 * @throws IOException
	 * @throws FileNotFoundException
	 */
	private static void writeProcesses(ProcessActivity pAct, Activity mainAct,
			Activity thisAct, ProcessDefinitionDocument rootDoc,
			ProcessDefinition root, Process process, Map<String, Boolean> map)
			throws FileNotFoundException, IOException {
		// Currently implemented as the part of a single workflow rather
		// than making it a different process included as the sub process
		// This is a sub process as suggested by the process icon

		// Function is null here and so it represents either a notification
		// or some custom state or a process state (sub process)
		// Now make the corresponding entry in the main rootDoc as a sub process
		Boolean bool = map.get(thisAct.getDisplayName());
		if (bool == null || !bool) {
			ProcessState processState = root.addNewProcessState();
			processState.setName(thisAct.getDisplayName());
			processState.addDescription(thisAct.getDisplayName()
					+ "Sub Process");
			SubProcess subProcess = processState.addNewSubProcess();
			subProcess.setName(thisAct.getDisplayName());

			for (ActivityTransition actTransition : pAct.getActTransition()) {
				if (actTransition.getToProcessActivityName() != null) {
					Transition transition = processState.addNewTransition();
					String name = getActivityByName(
							getProcessActivityByName(
									actTransition.getToProcessActivityName(),
									mainAct).getActivityName(), process)
							.getDisplayName();

					transition.setTo(name);
					if (pAct.getActTransition().size() != 1)
						transition
								.setName(actTransition
										.getFromProcessActivityName().equals(
												"*") ? name : actTransition
										.getFromProcessActivityName());
					transition.addDescription(getActivityByName(
							getProcessActivityByName(
									actTransition.getToProcessActivityName(),
									mainAct).getActivityName(), process)
							.getDisplayName());
					map.put(thisAct.getDisplayName(), true);
					populateTransitionBasedNodes(actTransition, rootDoc,
							process, mainAct, root, map);

				}
			}
			// Here it is required to the complete the other nodes
			ProcessDefinitionDocument rootDocChild = ProcessDefinitionDocument.Factory
					.newInstance();
			ProcessDefinitionDocument.ProcessDefinition rootChild = rootDocChild
					.addNewProcessDefinition();

			makeProcessDocument(process, rootDocChild, rootChild, thisAct,
					new HashMap<String, Boolean>());
		}
	}

	/**
	 * @param process
	 * @param mainAct
	 * @param rootDoc
	 * @param root
	 * @param pAct
	 * @param thisAct
	 * @param map
	 * @throws IOException
	 * @throws FileNotFoundException
	 */
	private static void writeFunctions(Process process, Activity mainAct,
			ProcessDefinitionDocument rootDoc, ProcessDefinition root,
			ProcessActivity pAct, Activity thisAct, Map<String, Boolean> map)
			throws FileNotFoundException, IOException {
		// One of the standard functions
		if (thisAct.getFunction().equalsIgnoreCase("WF_STANDARD.COMPARE")) {
			writeDecisionNodes(process, mainAct, rootDoc, root, pAct, thisAct,
					map);
		} else if (thisAct.getFunction().equalsIgnoreCase("WF_STANDARD.ASSIGN")) {
			writeAssignNodes(process, mainAct, rootDoc, root, pAct, thisAct,
					map);
		} else if (thisAct.getFunction().equalsIgnoreCase("WF_STANDARD.NOOP")
				&& thisAct.getName() != null
				&& thisAct.getName().startsWith("END")) {
			writeEndNodes(process, mainAct, rootDoc, root, pAct, thisAct, map);
		} else {
			writeNodes(process, mainAct, rootDoc, root, pAct, thisAct, map);
		}
	}

	private static void writeNodes(Process process, Activity mainAct,
			ProcessDefinitionDocument rootDoc, ProcessDefinition root,
			ProcessActivity pAct, Activity thisAct, Map<String, Boolean> map)
			throws FileNotFoundException, IOException {
		Boolean bool = map.get(thisAct.getDisplayName());
		if (bool == null || !bool) {
			if (thisAct != null
					&& thisAct.getFunction() != null
					&& thisAct.getFunction().equalsIgnoreCase(
							"WF_STANDARD.ORJOIN")) {
				for (ActivityTransition actNextTran : pAct.getActTransition()) {
					if (actNextTran.getToProcessActivityName() != null) {
						populateTransitionBasedNodes(actNextTran, rootDoc,
								process, mainAct, root, map);
						return;
					}
				}
			} else if (!(thisAct.getDisplayName().startsWith("Is") || thisAct
					.getDisplayName().startsWith("FYI"))) {
				addNode(process, mainAct, rootDoc, root, pAct, thisAct, map);

			} else if (thisAct.getDisplayName().startsWith("Is")) {

				addDecision(process, mainAct, rootDoc, root, pAct, thisAct, map);
				// map.put(node.getName(), true);

			} else if (thisAct.getDisplayName().startsWith("FYI")) {

				addMailNode(process, mainAct, rootDoc, root, pAct, thisAct, map);
				// map.put(node.getName(), true);
			}
		}

	}

	/**
	 * @param process
	 * @param mainAct
	 * @param rootDoc
	 * @param root
	 * @param pAct
	 * @param thisAct
	 * @param map
	 * @return
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	private static MailNode addMailNode(Process process, Activity mainAct,
			ProcessDefinitionDocument rootDoc, ProcessDefinition root,
			ProcessActivity pAct, Activity thisAct, Map<String, Boolean> map)
			throws FileNotFoundException, IOException {
		MailNode node = root.addNewMailNode();
		node.setName(thisAct.getDisplayName());
		node.setTo("#{" + pAct.getPerformRoleName() + "TODO}");
		Message msg = getMessageByName(thisAct.getMessage(), process);
		XmlString str = node.addNewSubject();
		str.setStringValue(msg.getSubject());
		XmlString str1 = node.addNewText();
		str1.setStringValue(msg.getBody() == null ? msg.getHtmlBody() : msg
				.getBody());
		node.addDescription(msg.getDescription());

		for (ActivityTransition actTran : pAct.getActTransition()) {
			String conditionExpression = "";
			for (ActivityAttributeValue actVal : pAct.getActAttrVal()) {
				if (actVal.getValueType() != null
						&& actVal.getValueType().equalsIgnoreCase("ITEMATTR")) {
					if (conditionExpression.startsWith("#")) {
						conditionExpression = conditionExpression
								+ actVal.getValue() + "}";
					} else
						conditionExpression = "#{" + actVal.getValue() + " == ";
				} else if (actVal.getValueType() != null
						&& actVal.getValueType().equalsIgnoreCase("CONSTANT")) {
					conditionExpression = conditionExpression + "'"
							+ actVal.getValue() + "'}";
				}
			}
			if (actTran.getToProcessActivityName() != null) {
				Transition transition = node.addNewTransition();
				String name = getActivityByName(
						getProcessActivityByName(
								actTran.getToProcessActivityName(), mainAct)
								.getActivityName(), process).getDisplayName();

				transition.setTo(name);
				transition.addDescription(name);
				if (pAct.getActTransition().size() != 1) {
					transition.setName(actTran.getFromProcessActivityName()
							.equals("*") ? name : actTran
							.getFromProcessActivityName());
					Condition condition = transition.addNewCondition();
					if (actTran.getFromProcessActivityName() != null
							&& actTran.getFromProcessActivityName()
									.equals("EQ")) {
						condition.setExpression(conditionExpression);
					} else {
						condition.setExpression("TODO");
					}

				}
				map.put(node.getName(), true);
				populateTransitionBasedNodes(actTran, rootDoc, process,
						mainAct, root, map);
			}
		}
		return node;
	}

	/**
	 * @param process
	 * @param mainAct
	 * @param rootDoc
	 * @param root
	 * @param pAct
	 * @param thisAct
	 * @param map
	 * @return
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	private static Decision addDecision(Process process, Activity mainAct,
			ProcessDefinitionDocument rootDoc, ProcessDefinition root,
			ProcessActivity pAct, Activity thisAct, Map<String, Boolean> map)
			throws FileNotFoundException, IOException {
		Decision node = root.addNewDecision();
		node.setName(thisAct.getDisplayName());
		node.addDescription(thisAct.getDisplayName());
		Delegation delegation = node.addNewHandler();
		delegation.setClass1("com.qcom.TODODecision");
		for (ActivityTransition actTran : pAct.getActTransition()) {
			if (actTran.getToProcessActivityName() != null) {
				Transition transition = node.addNewTransition();
				String name = getActivityByName(
						getProcessActivityByName(
								actTran.getToProcessActivityName(), mainAct)
								.getActivityName(), process).getDisplayName();

				transition.setTo(name);
				transition.addDescription(name);
				if (pAct.getActTransition().size() != 1) {
					transition.setName(actTran.getFromProcessActivityName()
							.equals("*") ? name : actTran
							.getFromProcessActivityName());
				}
				map.put(node.getName(), true);
				populateTransitionBasedNodes(actTran, rootDoc, process,
						mainAct, root, map);
			}
		}
		return node;
	}

	/**
	 * @param process
	 * @param mainAct
	 * @param rootDoc
	 * @param root
	 * @param pAct
	 * @param thisAct
	 * @param map
	 * @return
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	private static Node addNode(Process process, Activity mainAct,
			ProcessDefinitionDocument rootDoc, ProcessDefinition root,
			ProcessActivity pAct, Activity thisAct, Map<String, Boolean> map)
			throws FileNotFoundException, IOException {
		if (thisAct.getDisplayName() != null
				&& !thisAct.getDisplayName().equalsIgnoreCase("Loop Counter")) {
			Node node = root.addNewNode();
			node.setName(thisAct.getDisplayName());
			node.addDescription(thisAct.getDisplayName());

			map.put(node.getName(), true);
			addNodeTransitions(process, mainAct, rootDoc, root, pAct, map, node);
			return node;
		}

		return null;
	}

	private static void writeAssignNodes(Process process, Activity mainAct,
			ProcessDefinitionDocument rootDoc, ProcessDefinition root,
			ProcessActivity pAct, Activity thisAct, Map<String, Boolean> map)
			throws FileNotFoundException, IOException {
		Boolean bool = map.get(thisAct.getDisplayName());
		if (bool == null || !bool) {
			Node node = root.addNewNode();
			node.setName(thisAct.getDisplayName());
			node.addDescription(thisAct.getDisplayName());
			map.put(node.getName(), true);
			addNodeTransitions(process, mainAct, rootDoc, root, pAct, map, node);
		}
	}

	/**
	 * @param process
	 * @param mainAct
	 * @param rootDoc
	 * @param root
	 * @param pAct
	 * @param map
	 * @param node
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	private static void addNodeTransitions(Process process, Activity mainAct,
			ProcessDefinitionDocument rootDoc, ProcessDefinition root,
			ProcessActivity pAct, Map<String, Boolean> map, Node node)
			throws FileNotFoundException, IOException {
		for (ActivityTransition actTran : pAct.getActTransition()) {
			String conditionExpression = "";
			for (ActivityAttributeValue actVal : pAct.getActAttrVal()) {
				if (actVal.getValueType() != null
						&& actVal.getValueType().equalsIgnoreCase("ITEMATTR")) {
					if (conditionExpression.startsWith("#")) {
						conditionExpression = conditionExpression
								+ actVal.getValue() + "}";
					} else
						conditionExpression = "#{" + actVal.getValue() + " == ";
				} else if (actVal.getValueType() != null
						&& actVal.getValueType().equalsIgnoreCase("CONSTANT")) {
					conditionExpression = conditionExpression + "'"
							+ actVal.getValue() + "'}";
				}
			}
			if (actTran.getToProcessActivityName() != null) {
				Transition transition = node.addNewTransition();
				String name = getActivityByName(
						getProcessActivityByName(
								actTran.getToProcessActivityName(), mainAct)
								.getActivityName(), process).getDisplayName();

				transition.setTo(name);
				transition.addDescription(name);
				if (pAct.getActTransition().size() != 1) {
					transition.setName(actTran.getFromProcessActivityName()
							.equals("*") ? name : actTran
							.getFromProcessActivityName());
					Condition condition = transition.addNewCondition();
					if (actTran.getFromProcessActivityName() != null
							&& actTran.getFromProcessActivityName()
									.equals("EQ")) {
						condition.setExpression(conditionExpression);
					} else {
						condition.setExpression("TODO");
					}

				}

				populateTransitionBasedNodes(actTran, rootDoc, process,
						mainAct, root, map);
			}
		}
	}

	private static void writeEndNodes(Process process, Activity mainAct,
			ProcessDefinitionDocument rootDoc, ProcessDefinition root,
			ProcessActivity pAct, Activity thisAct, Map<String, Boolean> map)
			throws FileNotFoundException, IOException {
		// This is the decision module
		// It can be ANDJOIN, COMPARE DATE etc.
		Boolean bool = map.get(thisAct.getDisplayName());
		if (bool == null || !bool) {
			EndState endState = root.addNewEndState();
			endState.setName(thisAct.getDisplayName());
			endState.addDescription(thisAct.getDisplayName());
			map.put(endState.getName(), true);
		}
	}

	/**
	 * @param process
	 * @param mainAct
	 * @param rootDoc
	 * @param root
	 * @param pAct
	 * @param thisAct
	 * @param map
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	private static void writeDecisionNodes(Process process, Activity mainAct,
			ProcessDefinitionDocument rootDoc, ProcessDefinition root,
			ProcessActivity pAct, Activity thisAct, Map<String, Boolean> map)
			throws FileNotFoundException, IOException {
		// This is the decision module
		// It can be ANDJOIN, COMPARE DATE etc.
		Decision decision = root.addNewDecision();
		decision.setName(thisAct.getDisplayName());
		decision.addDescription(thisAct.getDisplayName());
		for (ActivityTransition actTran : pAct.getActTransition()) {
			String conditionExpression = "";
			for (ActivityAttributeValue actVal : pAct.getActAttrVal()) {
				if (actVal.getValueType() != null
						&& actVal.getValueType().equalsIgnoreCase("ITEMATTR")) {
					if (conditionExpression.startsWith("#")) {
						conditionExpression = conditionExpression
								+ actVal.getValue() + "}";
					} else
						conditionExpression = "#{" + actVal.getValue() + " == ";
				} else if (actVal.getValueType() != null
						&& actVal.getValueType().equalsIgnoreCase("CONSTANT")) {
					conditionExpression = conditionExpression + "'"
							+ actVal.getValue() + "'}";
				}
				// TODO : wt if the values come first. left for user to
				// edit in case In this case the user needs to replace
				// the values in the generated xml file so that all the
				// scenarios can be captured.

			}
			if (actTran.getToProcessActivityName() != null) {
				Transition transition = decision.addNewTransition();
				String name = getActivityByName(
						getProcessActivityByName(
								actTran.getToProcessActivityName(), mainAct)
								.getActivityName(), process).getDisplayName();

				transition.setTo(name);
				transition.addDescription(name);
				if (pAct.getActTransition().size() != 1) {
					transition.setName(actTran.getFromProcessActivityName()
							.equals("*") ? name : actTran
							.getFromProcessActivityName());
					Condition condition = transition.addNewCondition();
					if (actTran.getFromProcessActivityName() != null
							&& actTran.getFromProcessActivityName()
									.equals("EQ")) {
						condition.setExpression(conditionExpression);
					} else {
						condition.setExpression("TODO");
					}

				}

				populateTransitionBasedNodes(actTran, rootDoc, process,
						mainAct, root, map);
			}
		}
	}
}
